package br.com.petsis.funcionalidades.manterVale;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.faces.model.SelectItem;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.security.Restrict;
import org.jboss.seam.faces.FacesMessages;
import org.jboss.seam.international.StatusMessage.Severity;

import br.com.petsis.entity.Cliente;
import br.com.petsis.entity.Empresa;
import br.com.petsis.entity.Funcionario;
import br.com.petsis.entity.Perfil;
import br.com.petsis.entity.TipoVale;
import br.com.petsis.entity.Vale;

@Name("manterValeController")
@Scope(ScopeType.CONVERSATION)
@Restrict(value="#{!identity.hasRole('"+Perfil.PERFIL_VETERINARIA+"')}")
public class ManterValeController {
	
	private static final String QRY_FUNCIONARIOS = "select f.id_funcionario,f.dsc_nome from funcionario f where f.id_empresa = :idEmpresa and f.dta_saida is null and f.flg_ativo = 'T' order by f.dsc_nome";
	private static final String QRY_VALES = "select v.id_vale,v.id_tipo_vale,v.id_funcionario,v.dta_vale,v.vlr_vale,v.dsc_observacao from vale v where v.id_empresa = :idEmpresa and v.flg_ativo = 'T' order by v.dta_vale DESC";
	private static final String QRY_TIPOS_VALE = "select t from TipoVale t where t.empresa.idEmpresa = :idEmpresa and t.flgAtivo = 'T'";
	
	@In(create=true)
	private EntityManager entityManager;
	
	private List<SelectItem> listaFuncionarios;
	
	private List<Vale> listaVales;
	
	private List<SelectItem> listaTiposVale;
	
	private Vale valeEdicao;
	
	private boolean selecionadoTodos;
	
	private Integer idFuncionario;
	
	private Integer idTipoVale;
	
	private String filtroTipo;
	
	private String filtroFuncionario;
	
	private String filtroData;
	
	private String filtroValor;
	
	@In(required=false)
	private Empresa empresaSessao;
	
	public boolean filtrarValesPorTipo(Object current){
		Vale vale = (Vale)current;
		if(getFiltroTipo() == null || getFiltroTipo().isEmpty()){
			return true;
		}
		if(vale.getTipoVale().getDscTipoVale().toLowerCase().contains(getFiltroTipo().toLowerCase())){
			return true;
		}else{
			return false;
		}
	}
	
	public boolean filtrarValesPorFuncionario(Object current){
		Vale vale = (Vale)current;
		if(getFiltroFuncionario() == null || getFiltroFuncionario().isEmpty()){
			return true;
		}
		if(vale.getFuncionario() != null && 
				vale.getFuncionario().getDscNome() != null &&
				vale.getFuncionario().getDscNome().toLowerCase().contains(getFiltroFuncionario().toLowerCase())){
			return true;
		}else{
			return false;
		}
	}
	
	public boolean filtrarValesPorData(Object current){
		Vale vale = (Vale)current;
		if(getFiltroData() == null || getFiltroData().isEmpty()){
			return true;
		}
		SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
		if(sdf.format(vale.getDtaVale()).contains(getFiltroData().toLowerCase())){
			return true;
		}else{
			return false;
		}
	}
	
	public boolean filtrarValesPorValor(Object current){
		Vale vale = (Vale)current;
		if(getFiltroValor() == null || getFiltroValor().isEmpty()){
			return true;
		}
		if(vale.getVlrVale().toString().contains(getFiltroValor().replace(",", "."))){
			return true;
		}else{
			return false;
		}
	}
	
	public String getFiltroTipo() {
		return filtroTipo;
	}

	public void setFiltroTipo(String filtroTipo) {
		this.filtroTipo = filtroTipo;
	}

	public String getFiltroFuncionario() {
		return filtroFuncionario;
	}

	public void setFiltroFuncionario(String filtroFuncionario) {
		this.filtroFuncionario = filtroFuncionario;
	}

	public String getFiltroData() {
		return filtroData;
	}

	public void setFiltroData(String filtroData) {
		this.filtroData = filtroData;
	}

	public String getFiltroValor() {
		return filtroValor;
	}

	public void setFiltroValor(String filtroValor) {
		this.filtroValor = filtroValor;
	}

	public void onLoad(){
		
	}
	
	public void onLoadList(){
		
		valeEdicao = new Vale();
		setIdFuncionario(null);
		setIdTipoVale(null);
		setListaTiposVale(null);
		setListaFuncionarios(null);
	}
	
	public void excluir(){
		List<Vale> listaRemocao = new ArrayList<Vale>();
		for(Vale v : getListaVales()){
			if(v.isSelecionado()){
				v.setFlgAtivo('F');
				entityManager.merge(v);
				listaRemocao.add(v);
			}
		}
		entityManager.flush();
		getListaVales().removeAll(listaRemocao);
	}
	
	public String salvar(){
		if(empresaSessao == null){
			FacesMessages.instance().add(Severity.ERROR,"Somente empresas podem salvar vales.");
			return null;
		}
		getValeEdicao().setTipoVale(null);
		getValeEdicao().setEmpresa(empresaSessao);
		getValeEdicao().setTipoVale(entityManager.find(TipoVale.class, getIdTipoVale()));
		if(getValeEdicao().getTipoVale().getFlgFuncionarioObrigatorio().equals('T')){
			if(getIdFuncionario() == null){
				FacesMessages.instance().add(Severity.ERROR,"É obrigatório informar um funcionário.");
				return null;
			}
		}
		getValeEdicao().setFlgAtivo('T');
		getValeEdicao().setFuncionario(null);
		if(getIdFuncionario() != null){
			getValeEdicao().setFuncionario(entityManager.find(Funcionario.class, getIdFuncionario()));
		}
		Vale valeSalvo = entityManager.merge(getValeEdicao());
		/*if(!getListaVales().contains(valeSalvo)){
			getListaVales().add(valeSalvo);
		}*/
		valeEdicao = new Vale();
		setIdFuncionario(null);
		setIdTipoVale(null);
		entityManager.flush();
		setListaVales(null);
		getListaVales();
		FacesMessages.instance().add(Severity.INFO,"Vale salvo com sucesso.");
		return "persisted";
	}
	
	public String editar(Vale vale){
		valeEdicao = entityManager.find(Vale.class, vale.getIdVale());
		setIdFuncionario(valeEdicao.getFuncionario() != null ? valeEdicao.getFuncionario().getIdFuncionario() : null);
		setIdTipoVale(valeEdicao.getTipoVale().getIdTipoVale());
		return "editar";
	}

	public boolean isSelecionadoTodos() {
		return selecionadoTodos;
	}

	public void setSelecionadoTodos(boolean selecionadoTodos) {
		this.selecionadoTodos = selecionadoTodos;
	}
	
	public void selecionaTodos(){
		for(Vale f : getListaVales()){
			if(isSelecionadoTodos()){
				f.setSelecionado(true);
			}else{
				f.setSelecionado(false);
			}
		}
	}

	public List<SelectItem> getListaFuncionarios() {
		if (listaFuncionarios == null) {
			listaFuncionarios = new ArrayList<SelectItem>();
			listaFuncionarios.add(new SelectItem(null,"Selecione"));
			if(empresaSessao != null){
				List<Object[]> lista = entityManager.createNativeQuery(QRY_FUNCIONARIOS)
					.setParameter("idEmpresa", empresaSessao.getIdEmpresa())
					.getResultList(); 
				for(Object[] f : lista){
					listaFuncionarios.add(new SelectItem(Integer.parseInt(f[0].toString()),
							f[1] != null ? f[1].toString() : null));
				}
			}
		}
		return listaFuncionarios;
	}

	public void setListaFuncionarios(List<SelectItem> listaFuncionarios) {
		this.listaFuncionarios = listaFuncionarios;
	}

	public Vale getValeEdicao() {
		if (valeEdicao == null) {
			valeEdicao = new Vale();
		}
		return valeEdicao;
	}

	public void setValeEdicao(Vale valeEdicao) {
		this.valeEdicao = valeEdicao;
	}

	public String novoVale(){
		return "novo"; 
	}
	
	public String cancelar(){
		valeEdicao = new Vale();
		return "voltar";  
	}

	public List<Vale> getListaVales() {
		if (listaVales == null) {
			listaVales = new ArrayList<Vale>();
			if(empresaSessao != null){
				List<Object[]> lista = entityManager.createNativeQuery(QRY_VALES)
					.setParameter("idEmpresa", empresaSessao.getIdEmpresa())
					.getResultList();
				Vale v;
				for(Object[] o : lista){
					v = new Vale();
					v.setIdVale(Integer.parseInt(o[0].toString()));
					v.setDtaVale(o[3] != null ? (Date)o[3] : null);
					v.setVlrVale(o[4] != null ? Float.parseFloat(o[4].toString()) : null);
					v.setDscObservacao(o[5] != null ? o[5].toString() : null);
					TipoVale tv = new TipoVale();
					tv.setDscTipoVale(o[1] != null ? recuperaNomeTipoVale(Integer.parseInt(o[1].toString())) : null);
					v.setTipoVale(tv);
					Funcionario f = new Funcionario();
					f.setDscNome(o[2] != null ? recuperaNomeFuncionario(Integer.parseInt(o[2].toString())) : null);
					v.setFuncionario(f);
					listaVales.add(v);
				}
			}
		}
		return listaVales;
	}
	
	public String recuperaNomeTipoVale(Integer id){
		try{
			Object retorno = entityManager.createNativeQuery("select t.dsc_tipo_vale from tipo_vale t where t.id_tipo_vale = :id")
				.setParameter("id", id)
				.getSingleResult();
			if(retorno != null){
				return retorno.toString();
			}
		}catch (NoResultException e) {
			return null;
		}
		return null;
	}
	
	public String recuperaNomeFuncionario(Integer id){
		try{
			Object retorno = entityManager.createNativeQuery("select f.dsc_nome from funcionario f where f.id_funcionario = :id")
				.setParameter("id", id)
				.getSingleResult();
			if(retorno != null){
				return retorno.toString();
			}
		}catch (NoResultException e) {
			return null;
		}
		return null;
	}

	public void setListaVales(List<Vale> listaVales) {
		this.listaVales = listaVales;
	}

	public List<SelectItem> getListaTiposVale() {
		if (listaTiposVale == null) {
			listaTiposVale = new ArrayList<SelectItem>();
			listaTiposVale.add(new SelectItem(null,"Selecione"));
			if(empresaSessao != null){
				List<TipoVale> lista = entityManager.createQuery(QRY_TIPOS_VALE)
					.setParameter("idEmpresa", empresaSessao.getIdEmpresa())
					.getResultList();
				for(TipoVale t : lista){
					listaTiposVale.add(new SelectItem(t.getIdTipoVale(),t.getDscTipoVale()));
				}
			}
		}
		return listaTiposVale;
	}

	public void setListaTiposVale(List<SelectItem> listaTiposVale) {
		this.listaTiposVale = listaTiposVale;
	}

	public Integer getIdFuncionario() {
		return idFuncionario;
	}

	public void setIdFuncionario(Integer idFuncionario) {
		this.idFuncionario = idFuncionario;
	}

	public Integer getIdTipoVale() {
		return idTipoVale;
	}

	public void setIdTipoVale(Integer idTipoVale) {
		this.idTipoVale = idTipoVale;
	}
	
}
